// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

/**
 *        增强 滚动 容器
 * 
 *      事件:  快到底了  ,  下拉刷新
 * 
 *      this.node.on("快到底了", (t: cc.Event.EventCustom) => {
            this.load_data(() => {
                t.getUserData().resume_listen();
            });
        })
 */
const { ccclass, property } = cc._decorator;

@ccclass
export default class ScrollView_plus extends cc.Component {

    ///////////// 其他需要 过滤 的item 父节点
    @property([cc.Node])
    item_partens: cc.Node[] = [];

    @property({ displayName: "下一页阈值" })
    next_page_threshold = 0.9;

    _scroll_comp = null;
    protected onLoad(): void {
        this._scroll_comp = this.node.getComponent(cc.ScrollView);

        if (this._scroll_comp == null) {
            console.error("节点上没有发现 cc.ScrollView 组件");
        }
    }

    svBBoxRect: cc.Rect = null;
    content: cc.Node = null;

    _event_ing = false;
    protected start(): void {
        if (this._scroll_comp == null) return;

        let sv: cc.ScrollView = this.node.getComponent(cc.ScrollView)
        this.content = sv.content;
        
        ////////////////////////////// 监听滑动 , 发送事件
        if (sv.horizontal == true) { ///// 水平滑动
            this.node.on("scrolling", this.scroll_horizontal, this);
        } else {
            this.node.on("scrolling", this.scroll_vertical, this);
        }
    }

    ///////// 水平滑动
    scroll_horizontal() {
        if (this._event_ing == false && (-this._scroll_comp.getScrollOffset().x) / this._scroll_comp.getMaxScrollOffset().x > this.next_page_threshold) {
            this._event_ing = true;
            let t = new cc.Event.EventCustom('快到底了', true);
            t.setUserData(this);
            this.node.dispatchEvent(t);
        }
    }

    //////// 垂直滑动
    scroll_vertical() {
        if (this._event_ing == false && this._scroll_comp.getScrollOffset().y / this._scroll_comp.getMaxScrollOffset().y > this.next_page_threshold) {
            this._event_ing = true;
            let t = new cc.Event.EventCustom('快到底了', true);
            t.setUserData(this);
            this.node.dispatchEvent(t);
        }

        if (this._event_ing == false && this._scroll_comp.getScrollOffset().y < -200) {
            this._event_ing = true;
            let t = new cc.Event.EventCustom('下拉刷新', true);
            t.setUserData(this);
            this.node.dispatchEvent(t);
        }
    }

    resume_listen() {
        this._event_ing = false;
    }

    update(dt) {
        if (this._scroll_comp == null) return;

        // 获取 ScrollView Node 的左下角坐标在世界坐标系中的坐标
        let svLeftBottomPoint: cc.Vec2 = this.node.parent.convertToWorldSpaceAR(
            cc.v2(
                this.node.x - this.node.anchorX * this.node.width,
                this.node.y - this.node.anchorY * this.node.height
            )
        );

        // 求出 ScrollView 可视区域在世界坐标系中的矩形（碰撞盒）
        this.svBBoxRect = cc.rect(svLeftBottomPoint.x, svLeftBottomPoint.y, this.node.width, this.node.height);

        this.optDc(this.content);

        for (let i = 0; i < this.item_partens.length; i++) {
            const element = this.item_partens[i];
            this.optDc(element);
        }
    }


    optDc(n: cc.Node) {
        // 遍历 ScrollView Content 内容节点的子节点，对每个子节点的包围盒做和 ScrollView 可视区域包围盒做碰撞判断
        n.children.forEach((childNode: cc.Node) => {
            // 如果相交了，那么就显示，否则就隐藏
            if (childNode.getBoundingBoxToWorld().intersects(this.svBBoxRect)) {
                childNode.opacity = 255;
            } else {
                childNode.opacity = 0;
            }
        });
    }
}
